package jiuwu.gqz.audiorecord

import kotlin.experimental.and

class Adts {

    object utils {

        fun isSyncWord(b1: Byte, b2: Byte, b3: Byte): Boolean {
            return (b1 == 0xff.toByte()) and (b2 == 0xf1.toByte()) and (b3 == 0xfc.toByte())
        }

        fun findSyncWord(data: ByteArray, offset: Int, max: Int): Int {

            var index = offset

            while (index+6 < max) {
                if (isSyncWord(data[index], data[index + 1], data[index + 6])) {
                    break
                }
                index++
            }

            return if (index+6 >= max) -1 else index
        }

    }

    class header {
        var data = ByteArray(7)

        /*
            fixed_header
         */
        // MPEG标识，0=MPEG-4，1=MPEG-2
        fun getID(): Int {
            return (data[1] and 0x0F).toInt() shr 3
        }

        // 是否误码校验（CRC校验）：0=有，1=无
        fun getProtectionAbsent(): Int {
            return (data[1] and 1).toInt()
        }

        // AAC级别：1=AAC Main，2=AAC LC(Low Complexity)，3=AAC SSR(Scalable Sample Rate)，
        // 4=AAC LTP(Long Term Prediction)
        fun getProfile(): Int {
            return data[2].toInt() shr 6
        }

        // 采样率下标
        fun getSampleFreqIndex(): Int {
            return (data[2] and 0x3f).toInt() shr 2
        }

        // 标识声道数
        fun getChannelConfiguration(): Int {
            Byte.MAX_VALUE
            return ((data[2] and 1).toInt() shl 3) + ((data[3] and 0xc0.toByte()).toInt() shr 6)
        }

        /*
            variable_header
         */

        // ADTS帧的长度：含ADTS_HEADER长度和AAC编码数据长度
        // 即aac_frame_length = (protection_absent == 0 ? 9 : 7) + audio_data_length
        fun getAACFrameLen(): Int {
            return ((data[3] and 3).toInt() shl 11) +
                    (data[4].toInt() shl 3) +
                    (data[5].toInt() shr 5)
        }

        // 表示当前帧有number_of_raw_data_blocks_in_frame + 1 个原始帧
        // (一个AAC原始帧包含一段时间内1024个采样及相关数据)。
        fun getNumOfRawDataBlocksInFrame(): Int {
            return (data[6] and 3).toInt()
        }

        override fun toString(): String {
            return "ADTS_HEADER:  ID:${getID()}, ProtectionAbsent:${getProtectionAbsent()}, " +
                    "Profile:${getProfile()}, SampleFreqIndex:${getSampleFreqIndex()}, " +
                    "ChannelConfiguration:${getChannelConfiguration()}, AACFrameLen:${getAACFrameLen()}, " +
                    "NumOfRawDataBlocksInFrame:${getNumOfRawDataBlocksInFrame()}"
        }
    }

}